/**
 * dialog - jQuery xui
 *
 * Licensed under the GPL:
 *   http://www.gnu.org/licenses/gpl.txt
 *
 * Copyright 2013 xjb [ beymy.en@gmail.com ]
 *
 * 依赖
 *	panel
 */
(function($) {

    /**
     * wrap dialog and return content panel.
     */
    function wrapDialog(target) {
        var t = $(target);
        t.wrapInner('<div class="dialog-content"></div>');
        var contentPanel = t.children('div.dialog-content');
        contentPanel.attr('style', t.attr('style'));
        t.removeAttr('style').css('overflow', 'hidden');
        return contentPanel;
    }

    /**
     * 调整大小
     */
    function setSize(target, param) {
        var opts = $.data(target, 'dialog').options;
        if (param) {
            if (param.width) {
                opts.width = param.width;
            }
            if (param.height) {
                opts.height = param.height;
            }
            if (param.left != null) {
                opts.left = param.left;
            }
            if (param.top != null) {
                opts.top = param.top;
            }
        }
        $(target).panel('resize', opts);
    }

    /**
     * 移动窗口
     */
    function moveDialog(target, param) {
        var state = $.data(target, 'dialog');
        var opts = state.options;

        if (param) {
            if (param.left != null) {
                opts.left = param.left;
            }
            if (param.top != null) {
                opts.top = param.top;
            }
        }
        $(target).panel('move', state.options);
        state.dialog.css({
            left: opts.left,
            top: opts.top
        });

        opts.onMove.apply(target, [opts.left, opts.top]);
    }

    /**
     * 水平居中
     */
    function hcenter(target, tomove) {
        var state = $.data(target, 'dialog');
        var opts = state.options;
        var width = opts.width;
        if (isNaN(width)) {
            width = state.dialog.outerWidth();
        }
        if (opts.inline) {
            var parent = state.dialog.parent();
            opts.left = (parent.width() - width) / 2 + parent.scrollLeft();
        } else {
            opts.left = ($(window).outerWidth() - width) / 2 + $(document).scrollLeft();
        }
        if (tomove) {
            moveDialog(target);
        }
    }

    /**
     * 垂直居中
     */
    function vcenter(target, tomove) {
        var state = $.data(target, 'dialog');
        var opts = state.options;
        var height = opts.height;
        if (isNaN(height)) {
            height = state.dialog.outerHeight();
        }
        if (opts.inline) {
            var parent = state.dialog.parent();
            opts.top = (parent.height() - height) / 2 + parent.scrollTop();
        } else {
            opts.top = ($(window).outerHeight() - height) / 2 + $(document).scrollTop();
        }
        if (tomove) {
            moveDialog(target);
        }
    }

    /**
     * 构建窗口
     */
    function buildDialog(target) {
        var state = $.data(target, 'dialog');
        var opts = state.options;
        var contentPanel = state.contentPanel;
        var t = $(target);
        if (opts.buttons) {
            if ($.isArray(opts.buttons)) {
                $('div.dialog-button', target).remove();
                var buttons = $('<div class="dialog-button"></div>').appendTo(target);
                for (var i = 0; i < opts.buttons.length; i++) {
                    var p = opts.buttons[i];
                    var button = $('<a href="javascript:void(0)"></a>').appendTo(buttons);
                    if (p.handler) {
                        button[0].onclick = p.handler;
                    }
                    button.linkbutton(p);
                }
            } else {
                $(opts.buttons).addClass("dialog-button").appendTo(target);
            }
        } else {
            $('div.dialog-button', target).remove();
        }

        var dlg = $(target).panel($.extend({}, state.options, {
            border: false,
            closed: true, // close the panel
            cls: 'dialog',
            headerCls: 'dialog-header',
            bodyCls: 'dialog-body ' + (state.options.noheader ? 'dialog-body-noheader' : ''),
            onBeforeDestroy: function() {
                if (state.options.onBeforeDestroy.call(target) == false) {
                    return false;
                }
                if (state.mask) {
                    state.mask.remove();
                }
            },
            onClose: function() {
                if (state.mask) {
                    state.mask.hide();
                }

                state.options.onClose.call(target);
            },
            onOpen: function() {
                if (state.mask) {
                    state.mask.css({
                        width: (state.options.inline ? state.mask.parent().width() : getPageArea().width),
                        height: (state.options.inline ? state.mask.parent().height() : getPageArea().height),
                        display: 'block',
                        zIndex: $.fn.dialog.defaults.zIndex++
                    });
                }
                state.dialog.css('z-index', $.fn.dialog.defaults.zIndex++);

                state.options.onOpen.call(target);
            },
            onResize: function(width, height) {
                var opts = $(this).panel('options');
                $.extend(state.options, {
                    width: opts.width,
                    height: opts.height,
                    left: opts.left,
                    top: opts.top
                });
                //调整内容大小
                contentPanel.css({
		            width: (opts.height == 'auto' ? 'auto' : t.width()),
		            height: (opts.height == 'auto' ? 'auto' : t.height() - t.children('div.dialog-button')._outerHeight())
	        	});

                state.options.onResize.call(target, width, height);
            },
            onMinimize: function() {
                if (state.mask) {
                    state.mask.hide();
                }

                state.options.onMinimize.call(target);
            },
            onBeforeCollapse: function() {
                if (state.options.onBeforeCollapse.call(target) == false) {
                    return false;
                }
            },
            onExpand: function() {
                state.options.onExpand.call(target);
            }
        }));

        state.dialog = dlg.panel('panel');
        

        // 遮罩层
        if (state.mask) {
            state.mask.remove();
        }
        if (state.options.modal == true) {
            state.mask = $('<div class="dialog-mask"></div>').insertAfter(state.dialog);
            state.mask.css({
                width: (state.options.inline ? state.mask.parent().width() : getPageArea().width),
                height: (state.options.inline ? state.mask.parent().height() : getPageArea().height),
                display: 'none'
            });
        }

        // 居中
        if (state.options.left == null) {
            hcenter(target);
        }
        if (state.options.top == null) {
            vcenter(target);
        }
        moveDialog(target);

        if (state.options.closed == false) {
            dlg.dialog('open'); // 打开窗口
	        contentPanel.css({
	            width: (opts.height == 'auto' ? 'auto' : t.width()),
	            height: (opts.height == 'auto' ? 'auto' : t.height() - t.children('div.dialog-button')._outerHeight())
	        });
        }
    }

    /**
     * 绑定事件
     */
    function bindEvents(target) {
        var state = $.data(target, 'dialog');

        //窗口resize事件
        /*
        state.dialog.unbind('dialog').bind('_resize.dialog', function() {
            $(target).dialog('center');
        });
        */
    }

    function getPageArea() {
        return {
            width: Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth),
            height: Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight)
        }
    }

    $(window).resize(function() {
        $('body>div.dialog-mask').css(getPageArea());
    });

    $.fn.dialog = function(options, param) {
        if (typeof options == 'string') {
            var method = $.fn.dialog.methods[options];
            if (method) {
                return method(this, param);
            } else {
                return this.panel(options, param);
            }
        }

        options = options || {};
        return this.each(function() {
            var state = $.data(this, 'dialog');
            if (state) {
                $.extend(state.options, options);
            } else {
                state = $.data(this, 'dialog', {
                    options: $.extend({}, $.fn.dialog.defaults, $.fn.dialog.parseOptions(this), options),
                    contentPanel: wrapDialog(this)
                });
                if (!state.options.inline) {
                    document.body.appendChild(this);
                }
            }
            buildDialog(this);
            bindEvents(this);
        });
    };

    $.fn.dialog.methods = {
        options: function(jq) {
            var popts = jq.panel('options');
            var wopts = $.data(jq[0], 'dialog').options;
            return $.extend(wopts, {
                closed: popts.closed,
                collapsed: popts.collapsed,
                minimized: popts.minimized,
                maximized: popts.maximized
            });
        },
        dialog: function(jq) {
            return $.data(jq[0], 'dialog').dialog;
        },
        setTitle: function(jq, param) {
            return jq.each(function() {
                $(this).panel('setTitle', param);
            });
        },
        open: function(jq) {
            return jq.each(function() {
                $(this).panel('open');
            });
        },
        close: function(jq) {
            return jq.each(function() {
                $(this).panel('close');
            });
        },
        destroy: function(jq) {
            return jq.each(function() {
                $(this).panel('destroy');
            });
        },
        move: function(jq, param) {
            return jq.each(function() {
                moveDialog(this, param);
            });
        },
        hcenter: function(jq) {
            return jq.each(function() {
                hcenter(this, true);
            });
        },
        vcenter: function(jq) {
            return jq.each(function() {
                vcenter(this, true);
            });
        },
        center: function(jq) {
            return jq.each(function() {
                hcenter(this);
                vcenter(this);
                moveDialog(this);
            });
        }
    };

    $.fn.dialog.parseOptions = function(target) {
        return $.extend({}, $.fn.panel.parseOptions(target), $.parser.parseOptions(target, [{
            modal: 'boolean',
            inline: 'boolean'
        }]));
    };

    // 继承 $.fn.panel.defaults
    $.fn.dialog.defaults = $.extend({}, $.fn.panel.defaults, {
        // 覆盖panel属性
        title: '新窗口',
        minimizable: true,
        maximizable: true,
        closable: true,
        closed: false,
        // dialog新增属性
        zIndex: 9000,
        modal: false,
        inline: false, // true 在父元素里, false 置顶
        buttons: null
    });
})(jQuery);
